import Taro, { Events } from "@tarojs/taro";
import checkCodeState from "./WeBLEStateCode";
import BLEconst from "./BLEconstUtils";
import { ab2hex, string2buffer, hexToString } from "./utils";



const events = new Events()
const BLEDiscovery = (columns) => {
    Taro.startBluetoothDevicesDiscovery(

    ).then(
        // services: ['FEE7'],
        res => {
            console.log(res)
            if (res.errCode == 0) {
                getBLEDEivces(columns)

            } else {
                Taro.showToast({
                    title: '获取列表失败'
                })
            }


        }
    ).catch(err => {
        console.log(err)
    }).finally(() => {

    })

}

const getBLEDEivces = (columns) => {


    const devicesTimer = setInterval(
        () => {
            Taro.getBluetoothDevices().then(res => {
                console.log("列表：")
                console.log(res)
                if (res.devices.length > 0) {
                    let devices = res.devices

                    devices.forEach(element => {

                        let newObj = {};
                        newObj = element
                        newObj.value = element.deviceId
                        element = newObj;
                    });
                    columns.value = res.devices
                    clearInterval(devicesTimer)

                }
            }).catch(err => {
                console.log(err)
            }).finally(() => {
                // Taro.hideLoading()
            })
        }

        , 300)
}

//蓝牙运行打开
export const BLEInit = (columns) => {

    Taro.openBluetoothAdapter().then(res => {
        console.log(res)
        const resultCode = checkCodeState(res.errno);
        console.log(resultCode)


        if (resultCode.code == 0) {

            // Taro.hideLoading()
            BLEDiscovery(columns)
        }

    }).catch(err => {
        console.log(err)

    }).finally(() => {

    })

}
export const closeBLEDiscovery = () => {
    Taro.stopBluetoothDevicesDiscovery({
        success: function (res) {
            console.log(res)

        }
    })

}
export const closeBLEAdapter = () => {
    Taro.closeBluetoothAdapter({
        success: function (res) {
            console.log(res)
        }
    })
}

export const closeBLEConnection = (deviceId) => {
    Taro.closeBLEConnection({
        deviceId: deviceId,
    }).then((res) => {
        Taro.removeStorageSync(BLEconst.DEVICE_KEY)
        Taro.removeStorageSync(BLEconst.SERVICE_KEY)
        Taro.removeStorageSync(BLEconst.CHARACTERISTICS_NOTIFY_KEY)
        Taro.removeStorageSync(BLEconst.CHARACTERISTICS_WRITE_KEY)
        console.log(res)

    }).catch(err => {
        console.error(err)

    }).finally(() => {

    })

}

export const getBLEDviceServices = (colorData, sliderValue, state) => {
    const deviceObj = Taro.getStorageSync(BLEconst.DEVICE_KEY)
    if (deviceObj) {
        Taro.getBLEDeviceServices({ deviceId: deviceObj.deviceId }).then((res) => {
            // 保存服务
            Taro.setStorageSync(BLEconst.SERVICE_KEY, res.services[0])
            //获取Characteristics

            getBLEDeviceCharacteristics(colorData, sliderValue, state)
            console.log(res)
        }).catch((err) => {
            console.error(err)
            Taro.showToast({
                title: "获取当前连接蓝牙失败",
                icon: "error"
            })
        }).finally(() => {


        })
    } else {
        Taro.showToast({
            title: "没有连接任何蓝牙设备",
            icon: "error"
        })
    }

}
export const getBLEDeviceCharacteristics = (colorData, sliderValue, state) => {
    const deviceObj = Taro.getStorageSync(BLEconst.DEVICE_KEY)
    const serviceObj = Taro.getStorageSync(BLEconst.SERVICE_KEY)

    Taro.getBLEDeviceCharacteristics({
        deviceId: deviceObj.deviceId,
        serviceId: serviceObj.uuid
    }).then((res) => {
        Taro.setStorageSync(BLEconst.CHARACTERISTICS_KEY, res.characteristics)
        res.characteristics.forEach((element) => {
            //             indicate	boolean	该特征值是否支持 indicate 操作
            // notify	boolean	该特征值是否支持 notify 操作
            // read	boolean	该特征值是否支持 read 操作
            // write	boolean	该特征值是否支持 write 操作
            let charproperty = element.properties
            if (charproperty.indicate) {
                Taro.setStorageSync(BLEconst.CHARACTERISTICS_INDICATE_KEY, element)

            } else if (charproperty.notify) {
                Taro.setStorageSync(BLEconst.CHARACTERISTICS_NOTIFY_KEY, element)


            } else if (charproperty.read) {
                Taro.setStorageSync(BLEconst.CHARACTERISTICS_READ_KEY, element)


            } else if (charproperty.write) {
                Taro.setStorageSync(BLEconst.CHARACTERISTICS_WRITE_KEY, element)

            }


        })

        notifyBLECharacteristicValueChange(colorData, sliderValue, state)
        console.log(res)

    }).catch((err) => {
        console.error(err)

    }).finally(() => {

    })

}
export const writeBLECharacteristicValue = (value) => {

    const deviceObj = Taro.getStorageSync(BLEconst.DEVICE_KEY)
    const serviceObj = Taro.getStorageSync(BLEconst.SERVICE_KEY)
    const characteristicWriteObj = Taro.getStorageSync(BLEconst.CHARACTERISTICS_WRITE_KEY)

    // 向蓝牙设备发送一个0x00的16进制数据
    const buffer = string2buffer(JSON.stringify(value))
    if (deviceObj && serviceObj && characteristicWriteObj) {
        Taro.writeBLECharacteristicValue({
            // 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
            deviceId: deviceObj.deviceId,
            // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
            serviceId: serviceObj.uuid,
            // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
            characteristicId: characteristicWriteObj.uuid,
            // 这里的value是ArrayBuffer类型
            value: buffer
        }).then((res) => {
            console.log(res)
            console.log('writeBLECharacteristicValue success', res.errMsg)

        }).catch((err) => {
            Taro.showToast({ title: "请检查蓝牙配置", icon: "error" })
            console.error(err)
        }).finally(() => {

        })
    } else {
        Taro.showToast({ title: "请检查蓝牙配置", icon: "error" })
        return
    }

}
export const notifyBLECharacteristicValueChange = (colorData, sliderValue, state) => {
    const deviceObj = Taro.getStorageSync(BLEconst.DEVICE_KEY)
    const serviceObj = Taro.getStorageSync(BLEconst.SERVICE_KEY)
    const characteristicNOtifyObj = Taro.getStorageSync(BLEconst.CHARACTERISTICS_NOTIFY_KEY)
    if (deviceObj && serviceObj && characteristicNOtifyObj) {
        Taro.notifyBLECharacteristicValueChange({
            state: true, // 启用 notify 功能
            // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
            deviceId: deviceObj.deviceId,
            // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
            serviceId: serviceObj.uuid,
            // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
            characteristicId: characteristicNOtifyObj.uuid,
            success: function (res) {
                Taro.onBLECharacteristicValueChange(function (res) {
                    console.log(res)
                    console.log(`characteristic ${res.characteristicId} has changed, now is ${res.value}`)
                    const hex = ab2hex(res.value)
                    const jsonStr = hexToString(hex)
                    hardObj = JSON.parse(jsonStr)

                    if (hardObj.colorData) {
                        colorData.pickerData = hardObj.colorData.pickerData
                        colorData.hueData = hardObj.colorData.hueData
                        colorData.barY = hardObj.colorData.barY
                    }

                    console.log(colorData)
                    sliderValue.value = hardObj.light
                    Taro.setStorageSync(BLEconst.HARDWARE_KEY, hardObj)

                    Taro.redirectTo({
                        url: `/pages/index/index?colorData=${JSON.stringify(hardObj.colorData)}&sliderValue=${hardObj.light}&state=${JSON.stringify(state)} `
                    })

                })
                console.log('notifyBLECharacteristicValueChange success', res.errMsg)
            },
            fail: (err) => {
                Taro.showToast({ title: "请检查蓝牙配置", icon: "error" })
            },
            complete: () => {

            }
        })
    } else {
        Taro.showToast({ title: "请检查蓝牙配置", icon: "error" })
        return
    }

}
export const checkBLEConnectionStateChange = (state) => {
    const deviceObj = Taro.getStorageSync(BLEconst.DEVICE_KEY)

    Taro.onBLEConnectionStateChange((res) => {
        console.log(res.deviceId + '连接状态已经发生变化')
        console.log(res)
        if (!res.connected) {
            state.value = "";
            Taro.showToast({
                title: deviceObj.name + '蓝牙已断开连接，请尝试重新连接',
                icon: "none"
            })
        }
    })
}

export const createBLEConnection = (deviceId, itemParams, state, colorData, sliderValue) => {
    //创建连接之前关闭上一次连接
    const deviceObj = Taro.getStorageSync(BLEconst.DEVICE_KEY)
    if (deviceObj) {
        closeBLEConnection(deviceObj.deviceId)

    }
    Taro.showLoading({
        title: '正在建立连接',
        mask: true
    })
    Taro.createBLEConnection({
        // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
        deviceId: deviceId,
    }).then((res) => {
        console.log(res)
        state.val = itemParams.name;
        Taro.setStorageSync(BLEconst.DEVICE_KEY, itemParams)
        Taro.showToast({
            title: '连接成功...',
            mask: true,
            duration: 1000

        })
        checkBLEConnectionStateChange(state)
        getBLEDviceServices(colorData, sliderValue, state)




    }).catch((err) => {
        if (err.errCode) {

            const errObj = checkCodeState(err.errCode)
            console.log(errObj)

            Taro.showToast(
                {
                    title: errObj.text,
                    icon: "error",
                    duration: 1500
                }
            )
        }
        console.error(err)
    }).finally(() => {
        Taro.hideLoading()
        closeBLEDiscovery()

    })



}

